package client;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.Dimension;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**********************************************************
 * GROUP : HONEYBADGER MEMBERS: CHRISTOPHER CONRY, TYLER HERZOG DATE: FEBRUARY
 * 2012 CS 45231 INTERNET ENGINEERING 2012 SPRING INSTRUCTOR: JAVED KAHN
 ******* *************************************************/

@SuppressWarnings("serial")
public class Client extends JFrame implements ActionListener {
	Socket connection = null;

	InputStream inStream;
	DataInputStream inDataStream;
	PrintWriter sender = null;
	TextArea logDisplay;
	String message, address = null;
	Clientlistener listenerthread;
	int port = 0;
	boolean isConnected = false, nameSet = false, chat=false;
	URL myUrl;
	String name;

	// GUI Window objects
	JLabel clicked;
	JButton submit, connect, connectLocal;
	JPanel panel, centerpanel, connectpanel, submitpanel;
	JTextField textField, addressbar, portbar;
	JTextArea received, log;
	JScrollPane spane;
	Thread sleepingthread;

	/**********************************************************
	 * GROUP : HONEYBADGER 
	 * DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG 
	 * MAIN: SET UP CLIENT. CREATE THE WINDOW AND WINDOW LISTENER. AND START RUNCLIENT,
	 * WHICH CURRENTLY IS USED TO LISTEN FOR INFORMATION
	 *********************************************************/

	/*--------------------------------------------------------------------------------*/
	public static void main(String[] args) {
		Client client = new Client();
		client.setTitle("Honey Badger");
		client.pack(); // sets window size to fit components
		client.setVisible(true); // show it duh
		client.setSize(900, 450);
	}

	/**********************************************************
	 * GROUP : HONEYBADGER 
	 * DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG 
	 * CLIENT(): SETUP THE UI. ADDING ALL PANELS AND FIELD.
	 *********************************************************/
	public Client() {
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		WindowListener listener = new WindowAdapter() {
			//Handle what happends on window close (clicking X)
			public void windowClosing(WindowEvent e) {
				//check if connection has been made...
				if(connection!=null)
					sender.println("death");
				setVisible(false);
				System.exit(0);
			}
		};
		//GUI Window Stuff
		this.addWindowListener(listener);
		addressbar = new JTextField(40);
		textField = new JTextField(40);
		portbar = new JTextField(40);
		portbar.setColumns(5);
		submit = new JButton("Send it");
		connect = new JButton("Connect");
		connectLocal = new JButton("Local");
		received = new JTextArea(20, 20); // for messages from server
		Dimension size = new Dimension (400, 640);
		Dimension size2 = new Dimension (400, 2440);
		received.setPreferredSize(size2);
		received.setLineWrap(true);
		received.setWrapStyleWord(true);
		JScrollPane scrollPane = new JScrollPane(received);
		scrollPane.setPreferredSize(size);
		
		log = new JTextArea(20, 20); // log about the client
		log.setPreferredSize(size);
		submit.addActionListener(this);
		connect.addActionListener(this);
		connectLocal.addActionListener(this);
		panel = new JPanel();
		centerpanel = new JPanel();
		connectpanel = new JPanel();
		submitpanel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.setBackground(Color.white);
		getContentPane().add(panel);
		panel.add(connectpanel, BorderLayout.NORTH);
		panel.add(centerpanel, BorderLayout.CENTER);
		panel.add(submitpanel, BorderLayout.SOUTH);
		connectpanel.add(addressbar);
		connectpanel.add(portbar);
		connectpanel.add(connect);
		connectpanel.add(connectLocal);
		centerpanel.add(scrollPane);
		centerpanel.add(log);
		submitpanel.add(textField);
		submitpanel.add(submit);
		log.append("This is the log where client info goes\n"
				+ "Type your messages in the box below \n\n Connect First, then enter" +
				"a name to use (10 char max)\n\n");
		received.append("Messages from the server will show up here \n");
		

	}

	/**********************************************************
	 * GROUP : HONEYBADGER 
	 * DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG
	 * ACTIONPREFORMED: THIS IS USED TO HANDLE ALL EVENTS FROM BUTTONS.
	 * INCLUDING CONNECT, CONNECT LOCAL AND SUBMIT
	 *********************************************************/
	public void actionPerformed(ActionEvent event) {
		Object source = event.getSource();
		if (source == connect) {
			this.makeConnection(addressbar.getText(),
					Integer.parseInt(portbar.getText()));
		}
		if (source == connectLocal) {
			this.makeConnection("local", 8080);
		}
		if (source == submit) { // send the data over the socket
			// check message for a command. Options include send, url, get
			if(nameSet == false) {
				int length = textField.getText().length();
				if(length > 10) {
					log.append("name too long, try again");
					textField.setText(new String(""));
				}
				else{
					name = textField.getText().substring(0,length);
					log.append("Hi "+name+"\n");
					nameSet= true;
					textField.setText(new String(""));
					sender.println("NAME " + name);
				}
			}
			else { //name already set, doing commands
				try {
					if(chat){
						message = textField.getText();
						if(!message.equals("/quit")){
							//System.out.println(message);
							sender.println(message);}
						else {
							chat=false;
							log.append("Chat mode exited...\n");
							sender.println(message);
						}
					}
					else{
						if (textField.getText().substring(0,4).toUpperCase().equals("CHAT")){
							sender.println("CHAT ");
							chat = true;
							log.append("Now in chat mode. Everything typed will be broadcasted.\n Type /quit to leave. ");
						} else if (textField.getText().substring(0, 3).equals("url")) {
							ReadURL(textField.getText().substring(4));
						} else if (textField.getText().substring(0, 3).equals("get")) {
							sender.println(textField.getText()+ " "); // need to send whole
							// message to
							log.append("File request sent to server for: "
									+ textField.getText().substring(4) + "\n");
							// server to interpret
						} else
							log.append("Available commands: chat, get, url \n");
					}
				} catch (IndexOutOfBoundsException e) {
				}

				// reset our text field value
				textField.setText(new String(""));
				// code to receive answer from server
			}
		}
	}

	/**********************************************************
	 * GROUP : HONEYBADGER 
	 * DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG 
	 * READURL():PARSES THE URL. OUTPUTS INFORMATION FROM THE URL
	 *********************************************************/
	public void ReadURL(String url) {
		// create a URL object from the string passed
		try {
			myUrl = new URL(url);
			log.append("The url given was: " + url + "\n");
			// isolate the protocol scheme (http)
			log.append("The protocol is: " + myUrl.getProtocol() + "\n");
			// isolate the domain name of server
			log.append("The host name is: " + myUrl.getHost() + "\n");
			// the port number
			log.append("The port number is: " + myUrl.getPort() + "\n");
			// the target name
			log.append("The path is: " + myUrl.getPath() + "\n");
		} catch (MalformedURLException e) {
			log.append("There was an error parsing your URL, aborting... \n");
		}
	}

	/**********************************************************
	 * GROUP : HONEYBADGER DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG
	 * MAKECONNECTION(): CREATES CONNECTION TO SERVER. SETUP SOCKET. CREATE
	 * INPUT DATA STREAM. AND STARTS THE CLIENTLISTENER().
	 *********************************************************/
	public void makeConnection(String address, int port) {
		log.append("Attempting to connect to new address...\n");
		try {
			if (address.equals("local"))
				address = InetAddress.getLocalHost().getHostAddress();
			connection = new Socket(address, port);
			inStream = connection.getInputStream();
			inDataStream = new DataInputStream(inStream);
			sender = new PrintWriter(connection.getOutputStream(), true);
			listenerthread = new Clientlistener(inDataStream, received);
			isConnected = true;
			listenerthread.start();

		} catch (UnknownHostException e) {
			log.append("Failed to connect through socket");
		} catch (IOException e) { log.append("There was an IO Exception, fix it\n");
		}
		log.append("Connection Established \n");

	}


	/*--------------------------------------------------------------------------------*/
	// WindowListener Stuffs
	public void windowActivated(WindowEvent e) {
	}

	public void windowDeactivated(WindowEvent e) {
	}

	public void windowOpened(WindowEvent e) {
	}

	public void windowClosed(WindowEvent e) {
		sender.println("death");
	}

	/**********************************************************
	 * GROUP : HONEYBADGER DEVELOPER: CHRISTOPHER CONRY, TYLER HERZOG
	 * WINDOWCLOSING(): HANDLES THE WINDOW CLOSING.
	 *********************************************************/
	public void windowClosing(WindowEvent e) {
		sender.println("death");
		this.setVisible(false);
		this.dispose();
		
		try {
			connection.close();
		} catch (IOException e1) {

		}

		listenerthread.kill();
		System.exit(0);
	}

	public void windowIconified(WindowEvent e) {
	}

	public void windowDeiconified(WindowEvent e) {
	}
}
